home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
c
/
newmat.exe
/
NEWMAT7.CXX
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-30
|
11KB
|
348 lines
//$$ newmat7.cxx Invert, solve, binary operations
// Copyright (C) 1991: R B Davies and DSIR
#include "include.hxx"
#include "boolean.hxx"
typedef double real; // all floating point double
#include "newmat.hxx"
#include "newmatrc.hxx"
//#define REPORT { static ExeCounter ExeCount(__LINE__,7); ExeCount++; }
#define REPORT {}
/***************************** solve routines ******************************/
GeneralMatrix* GeneralMatrix::MakeSolver()
{
REPORT
GeneralMatrix* gm = new CroutMatrix(*this);
MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;
}
GeneralMatrix* Matrix::MakeSolver()
{
REPORT
GeneralMatrix* gm = new CroutMatrix(*this);
MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;
}
void CroutMatrix::Solver(MatrixRowCol& mcout, const MatrixRowCol& mcin)
{
REPORT
real* el = mcin.store; int i = mcin.skip;
while (i--) *el++ = 0.0;
el += mcin.storage; i = nrows - mcin.skip - mcin.storage;
while (i--) *el++ = 0.0;
lubksb(mcin.store, mcout.skip);
}
// Do we need check for entirely zero output?
void UpperTriangularMatrix::Solver(MatrixRowCol& mcout,
const MatrixRowCol& mcin)
{
REPORT
real* elx = mcin.store+mcout.skip; int i = mcin.skip-mcout.skip;
while (i-- > 0) *elx++ = 0.0;
int nr = mcin.skip+mcin.storage; elx = mcin.store+nr; real* el = elx;
int j = mcout.skip+mcout.storage-nr; int nc = ncols-nr; i = nr-mcout.skip;
while (j-- > 0) *elx++ = 0.0;
real* Ael = store + (nr*(2*ncols-nr+1))/2; j = 0;
while (i-- > 0)
{
elx = el; real sum = 0.0; int jx = j++; Ael -= nc;
while (jx--) sum += *(--Ael) * *(--elx);
elx--; *elx = (*elx - sum) / *(--Ael);
}
}
void LowerTriangularMatrix::Solver(MatrixRowCol& mcout,
const MatrixRowCol& mcin)
{
REPORT
real* elx = mcin.store+mcout.skip; int i = mcin.skip-mcout.skip;
while (i-- > 0) *elx++ = 0.0;
int nc = mcin.skip; i = nc+mcin.storage; elx = mcin.store+i;
int nr = mcout.skip+mcout.storage; int j = nr-i; i = nr-nc;
while (j-- > 0) *elx++ = 0.0;
real* el = mcin.store+nc; real* Ael = store + (nc*(nc+1))/2; j = 0;
while (i-- > 0)
{
elx = el; real sum = 0.0; int jx = j++; Ael += nc;
while (jx--) sum += *Ael++ * *elx++;
*elx = (*elx - sum) / *Ael++;
}
}
/******************* carry out binary operations *************************/
static void Add(GeneralMatrix*,GeneralMatrix*, GeneralMatrix*);
static void Add(GeneralMatrix*,GeneralMatrix*);
static void Subtract(GeneralMatrix*,GeneralMatrix*, GeneralMatrix*);
static void Subtract(GeneralMatrix*,GeneralMatrix*);
static void ReverseSubtract(GeneralMatrix*,GeneralMatrix*);
static GeneralMatrix* GeneralAdd(GeneralMatrix*,GeneralMatrix*,MatrixType);
static GeneralMatrix* GeneralSub(GeneralMatrix*,GeneralMatrix*,MatrixType);
static GeneralMatrix* GeneralMult(GeneralMatrix*,GeneralMatrix*,MatrixType);
static GeneralMatrix* GeneralSolv(GeneralMatrix*,GeneralMatrix*,MatrixType);
GeneralMatrix* AddedMatrix::Evaluate(MatrixType mt)
{ REPORT return GeneralAdd(bm1->Evaluate(), bm2->Evaluate(), mt); }
GeneralMatrix* SubtractedMatrix::Evaluate(MatrixType mt)
{ REPORT return GeneralSub(bm1->Evaluate(), bm2->Evaluate(), mt); }
GeneralMatrix* MultipliedMatrix::Evaluate(MatrixType mt)
{
REPORT
GeneralMatrix* gm2 = bm2->Evaluate();
MatrixType mtsym(MatrixType::Sym);
if (gm2->Type() == mtsym) gm2 = gm2->Evaluate(MatrixType::Rect);
return GeneralMult(bm1->Evaluate(), gm2, mt);
}
GeneralMatrix* SolvedMatrix::Evaluate(MatrixType mt)
{ REPORT return GeneralSolv(bm1->Evaluate(), bm2->Evaluate(), mt); }
// routines for adding or subtracting matrices of identical storage structure
static void Add(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
{
REPORT
register real* s1=gm1->Store(); register real* s2=gm2->Store();
register real* s=gm->Store(); register int i=gm->Storage();
while (i--) *s++ = *s1++ + *s2++;
}
static void Add(GeneralMatrix* gm, GeneralMatrix* gm2)
{
REPORT
register real* s2=gm2->Store();
register real* s=gm->Store(); register int i=gm->Storage();
while (i--) *s++ += *s2++;
}
static void Subtract(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
{
REPORT
register real* s1=gm1->Store(); register real* s2=gm2->Store();
register real* s=gm->Store(); register int i=gm->Storage();
while (i--) *s++ = *s1++ - *s2++;
}
static void Subtract(GeneralMatrix* gm, GeneralMatrix* gm2)
{
REPORT
register real* s2=gm2->Store();
register real* s=gm->Store(); register int i=gm->Storage();
while (i--) *s++ -= *s2++;
}
static void ReverseSubtract(GeneralMatrix* gm, GeneralMatrix* gm2)
{
REPORT
register real* s2=gm2->Store();
register real* s=gm->Store(); register int i=gm->Storage();
while (i--) { *s = *s2++ - *s; s++; }
}
static GeneralMatrix* GeneralAdd(GeneralMatrix* gm1, GeneralMatrix* gm2,
MatrixType mtx)
{
int nr=gm1->Nrows(); int nc=gm1->Ncols();
if (nr!=gm2->Nrows() || nc!=gm2->Ncols())
MatrixError("Incompatible dimensions");
if (!mtx) mtx = gm1->Type() + gm2->Type();
if (mtx == gm1->Type() && mtx == gm2->Type())
// modify when band or sparse
// matrices are included.
{
if (gm1->reuse()) { REPORT Add(gm1,gm2); gm2->tDelete(); return gm1; }
else if (gm2->reuse()) { REPORT Add(gm2,gm1); return gm2; }
else
{
REPORT
GeneralMatrix* gmx = gm1->Type().New(nr,nc); gmx->ReleaseAndDelete();
gmx->ReleaseAndDelete(); Add(gmx,gm1,gm2); return gmx;
}
}
else
{
if (gm1->Type()==mtx && gm1->reuse() ) // must have type test first
{
REPORT
MatrixRow mr1(gm1, StoreOnExit+LoadOnEntry+DirectPart);
MatrixRow mr2(gm2, LoadOnEntry);
while (nr--) { mr1.Add(mr2); mr1.Next(); mr2.Next(); }
gm2->tDelete(); return gm1;
}
else if (gm2->Type()==mtx && gm2->reuse() )
{
REPORT
MatrixRow mr1(gm1, LoadOnEntry);
MatrixRow mr2(gm2, StoreOnExit+LoadOnEntry+DirectPart);
while (nr--) { mr2.Add(mr1); mr1.Next(); mr2.Next(); }
if (gm1->Type()!=mtx) gm1->tDelete();
return gm2;
}
else
{
REPORT
GeneralMatrix* gmx = mtx.New(nr,nc);
MatrixRow mr1(gm1, LoadOnEntry);
MatrixRow mr2(gm2, LoadOnEntry);
MatrixRow mrx(gmx, StoreOnExit+DirectPart);
while (nr--)
{ mrx.Add(mr1,mr2); mr1.Next(); mr2.Next(); mrx.Next(); }
if (gm1->Type()!=mtx) gm1->tDelete();
if (gm2->Type()!=mtx) gm2->tDelete();
gmx->ReleaseAndDelete(); return gmx;
}
}
}
static GeneralMatrix* GeneralSub(GeneralMatrix* gm1, GeneralMatrix* gm2,
MatrixType mtx)
{
if (!mtx) mtx = gm1->Type() - gm2->Type();
int nr=gm1->Nrows(); int nc=gm1->Ncols();
if (nr!=gm2->Nrows() || nc!=gm2->Ncols())
MatrixError("Incompatible dimensions");
if (mtx == gm1->Type() && mtx == gm2->Type())
// modify when band or sparse
// matrices are included.
{
if (gm1->reuse())
{ REPORT Subtract(gm1,gm2); gm2->tDelete(); return gm1; }
else if (gm2->reuse()) { REPORT ReverseSubtract(gm2,gm1); return gm2; }
else
{
REPORT
GeneralMatrix* gmx = gm1->Type().New(nr,nc); gmx->ReleaseAndDelete();
gmx->ReleaseAndDelete(); Subtract(gmx,gm1,gm2); return gmx;
}
}
else
{
if (gm1->Type() == mtx && gm1->reuse() )
{
REPORT
MatrixRow mr1(gm1, LoadOnEntry+StoreOnExit+DirectPart);
MatrixRow mr2(gm2, LoadOnEntry);
while (nr--) { mr1.Sub(mr2); mr1.Next(); mr2.Next(); }
gm2->tDelete(); return gm1;
}
else if (gm2->Type() == mtx && gm2->reuse() )
{
REPORT
MatrixRow mr1(gm1, LoadOnEntry);
MatrixRow mr2(gm2, LoadOnEntry+StoreOnExit+DirectPart);
while (nr--) { mr2.RevSub(mr1); mr1.Next(); mr2.Next(); }
if (gm1->Type()!=mtx) gm1->tDe